package com.gradle.quartz.batch.config;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.gradle.bean.user.User;
import com.gradle.quartz.batch.prestatement.UserPreStatementSetter;
import org.springframework.batch.core.Job;
import org.springframework.batch.core.Step;
import org.springframework.batch.core.configuration.annotation.EnableBatchProcessing;
import org.springframework.batch.core.configuration.annotation.JobBuilderFactory;
import org.springframework.batch.core.configuration.annotation.StepBuilderFactory;
import org.springframework.batch.core.launch.support.RunIdIncrementer;
import org.springframework.batch.core.step.tasklet.Tasklet;
import org.springframework.batch.item.database.JdbcBatchItemWriter;
import org.springframework.batch.item.database.PagingQueryProvider;
import org.springframework.batch.item.database.builder.JdbcBatchItemWriterBuilder;
import org.springframework.batch.item.database.support.SqlPagingQueryProviderFactoryBean;
import org.springframework.batch.item.json.JacksonJsonObjectReader;
import org.springframework.batch.item.json.JsonItemReader;
import org.springframework.batch.item.json.builder.JsonItemReaderBuilder;
import org.springframework.batch.repeat.RepeatStatus;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.InputStreamResource;
import javax.sql.DataSource;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;

/**
 * 逻辑现有两条
 * 第一条普通任务 job ---> step ---> tasklet
 * 第二条：要读取文件
 * job ---> step ---> chunk ---> reader ----> writer
 */
@EnableBatchProcessing
@Configuration
public class JdbcBatchConfig {
    @Autowired
    private JobBuilderFactory jobBuilderFactory;
    @Autowired
    private StepBuilderFactory stepBuilderFactory;
    @Autowired
    private DataSource druidDataSource;
    @Autowired
    private UserPreStatementSetter userPreStatementSetter;

    @Bean
    public JdbcBatchItemWriter<User> jdbcBatchItemWriter() {
        return new JdbcBatchItemWriterBuilder<User>()
                .dataSource(druidDataSource)
                .sql("insert into user(id,userName,age,address) values(?,?,?,?)")
                .itemPreparedStatementSetter(userPreStatementSetter)
                .build();
    }


    @Bean
    public PagingQueryProvider jdbcPagingQueryProvider() throws Exception {
        SqlPagingQueryProviderFactoryBean pageBean = new SqlPagingQueryProviderFactoryBean();
        pageBean.setDataSource(druidDataSource);
        pageBean.setSelectClause("select *");
        pageBean.setFromClause("from user ");
        pageBean.setWhereClause("where id < :id");
        pageBean.setSortKey("id");
        return pageBean.getObject();
    }

    //    @Bean
//    public JdbcPagingItemReader<User> jdbcCursorItemReader() throws Exception {
//        Map<String,Object> map = new HashMap<>();
//        map.put("id","5");
//        return new JdbcPagingItemReaderBuilder<User>()
//                .name("jdbcItemReader1")
//                .dataSource(druidDataSource)
//                .rowMapper(userRowMapper())
//                //分页逻辑
//                .queryProvider(pagingQueryProvider())
//                .parameterValues(map)
//                .pageSize(10)
//                .build();
//    }

    @Bean
    public JsonItemReader<User> jdbcJsonItemReader() throws FileNotFoundException {
        ObjectMapper objectMapper = new ObjectMapper();
        JacksonJsonObjectReader<User> userReader = new JacksonJsonObjectReader<>(User.class);
        userReader.setMapper(objectMapper);
        File file = new File("D:\\workspace\\mygradleproject\\gradle-quartz\\src\\main\\resources\\file\\user.json");
        return new JsonItemReaderBuilder<User>()
                .name("userJsonItemReader")
                .resource(new InputStreamResource(new FileInputStream(file)))
                .jsonObjectReader(userReader)
                .build();
    }

    /**
     * 处理任务的逻辑对象
     *
     * @return Tasklett
     */
    @Bean
    public Tasklet jdbcTaskLet() {
        return (contribution, chunkContext) -> {
            System.out.println(">>>>>>>>>jsonTaskLet->处理任务的逻辑对象【jsonTaskLet】>>>>>>>>");
            return RepeatStatus.FINISHED;
        };
    }

    @Bean("jsonStep")
    public Step jdbcStep() throws Exception {
        System.out.println(">>>>>>>>>jsonStep-->【jsonStep】>>>>>>>>");
        return stepBuilderFactory.get("step2")
                //一次性读多少数据,以及数据类型为User
                .<User, User>chunk(1)
                .reader(jdbcJsonItemReader())
                .writer(jdbcBatchItemWriter())
                .build();
    }

    @Bean("jdbcJob")
    public Job jdbcJob() throws Exception {
        System.out.println(">>>>>>>>>jsonJob--> 任务启动执行对象【jsonJob】>>>>>>>>");
        return jobBuilderFactory.get("jdbc-job1")
                .start(jdbcStep())
                .incrementer(new RunIdIncrementer())
                .build();
    }
}
